/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "Window.h"
#include "MBT_Engine.h"

#include <场景/场景.h>


#include <map>
#include <imm.h>
#include <time.h>
using namespace std;




//#define M (-1);


#pragma comment(lib, "imm32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "D:/U/DEV/SDL/lib/x64/SDL2.lib")


//#include <GLFW/glfw3.h>
#include <SDL.h>
#include <SDL_syswm.h>



//int f_异步事件(void *userdata, SDL_Event * event);
LRESULT CALLBACK Windows窗口回调(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);



#define IDM_EXIT				105
#define IDC_PROJECT1			109

#define VK_LSHIFT 0xA0 
#define VK_RSHIFT 0xA1 
#define VK_LCONTROL 0xA2 


static float64 gdur;

static clock_t g时间start = clock();
static clock_t g时间end;

static float64 g帧数计时;
static clock_t g帧数计时start = clock();
static clock_t g帧数计时end;

static HINSTANCE m_hInstance = 0;


std::wstring f_win32_get输入法文本(HIMC hImc);


Inline bool f_window_set鼠标样式(E_鼠标样式 样式) {
	HCURSOR s;
	switch (样式) {
		//case E_鼠标样式::e_鼠标样式_默认:		s = LoadCursor(NULL, IDC_ARROW);	break;
		//case E_鼠标样式::e_鼠标样式_默认:		return false;
		case E_鼠标样式::e_鼠标样式_横向双箭头: s = LoadCursor(NULL, IDC_SIZEWE); break;
		case E_鼠标样式::e_鼠标样式_纵向双箭头: s = LoadCursor(NULL, IDC_SIZENS); break;
		case E_鼠标样式::e_鼠标样式_等待:       s = LoadCursor(NULL, IDC_WAIT);   break;

		default:
			return false;
	}

	SetCursor(s);
	return true;
}

LPCWSTR stringToLPCWSTR(std::string orig) {
	size_t origsize = orig.length() + 1;
	const size_t newsize = 100;
	size_t convertedChars = 0;
	wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(orig.length() - 1));
	mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);

	return wcstring;
}

inline HINSTANCE GetCurrentModule(string path="") {
	if (path.empty()) {
		return GetModuleHandle(0);
	}
	//return GetModuleHandle(path.c_str());
	return GetModuleHandle(stringToLPCWSTR(path));
}





S_Window::S_Window(S_设备环境& Ctx) {
	//m_绘图API = apiName;
	m_TypeName = "窗口";
	m_弹出窗口 = false;

	m_绘图设备配置 = nullptr;
	m_绘图框架 = nullptr;
	m_窗口GM = nullptr;
	m_Window = nullptr;
	m_采样 = E_MS次数::e_MS_4;
	m_帧数 = 0;
	
	m_可视 = true;
	m_是否有焦点 = true;
	m_Input = f_input_create输入设备();

	

	if (!m_hInstance) {
		m_hInstance = GetCurrentModule();

		WNDCLASS wc = {};
		wc.style = CS_HREDRAW | CS_VREDRAW;
		wc.lpfnWndProc = Windows窗口回调;
		wc.cbClsExtra = 0;
		wc.cbWndExtra = 0;
		wc.hInstance = m_hInstance;
		wc.hIcon = LoadIcon(0, IDI_APPLICATION);
		wc.hCursor = LoadCursor(0, IDC_ARROW);
		wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
		wc.lpszMenuName = 0;
		//wc.lpszClassName = L"天瀑";
		wc.lpszClassName = L"只眼";

		if (!RegisterClass(&wc)) {
			MessageBox(0, L"RegisterClass Failed.", 0, 0);
			return;
		}
	}
}

S_Window::~S_Window() {
	CloseWindow((HWND)m_窗口钩柄);
	DestroyWindow((HWND)m_窗口钩柄);


	if (m_Input->m_鼠标设备) {
		f_input_release输入设备(m_Input);
	}
	
	f_release组件管理(m_窗口GM);
	m_窗口GM = 0;

	if (m_绘图设备配置) {
		f_draw_销毁绘图设备(m_绘图设备配置);
	}
	
	delete m_UIctx;
	m_UIctx = nullptr;

	
	S_Engine::g_窗口容器.erase((uint64)m_窗口钩柄);
}





uint64 S_Window::f_创建窗口(string 标题, int32 x, int32 y, int32 w, int32 h, int32 style, string path) {
	m_Size.x = w;
	m_Size.y = h;
	m_绘制 = true;

	std::wstring mMainWndCaption = L"只眼";
	RECT R = { 0, 0, w, h };
	AdjustWindowRect(&R, WS_OVERLAPPEDWINDOW, false);
	int width = R.right - R.left;
	int height = R.bottom - R.top;

	m_hWnd = CreateWindow(L"只眼", mMainWndCaption.c_str(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, width, height, 0, 0, m_hInstance, 0);
	if (!m_hInstance) {
		MessageBox(0, L"CreateWindow Failed.", 0, 0);
		return 0; 
	}

	m_窗口钩柄 = (S_结构对象指针)m_hWnd;
	ShowWindow((HWND)m_hWnd, SW_SHOW);
	UpdateWindow((HWND)m_窗口钩柄);
	HWND hWnd = GetForegroundWindow();
	
	DragAcceptFiles(hWnd, true);

	f_initInput(m_Input, m_窗口钩柄, (S_结构对象指针)m_hInstance);
	S_Engine::g_窗口容器[(uint64)m_窗口钩柄] = this;
	return 0;
}

void S_Window::f_窗口重置() {
	int32 w, h;
	SDL_GetWindowSize((SDL_Window*)m_Window, &w, &h);
	//m_engine.f_设置窗口尺寸(m_窗口大小[0], m_窗口大小[1]);
}


//SDL_Event event;
bool S_Window::f_轮询窗口事件() {
	if (!m_可视) return false;
	

	MSG msg = { 0 };
	if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
		//cout << "msg.message A:" << msg.message << " == " << m_帧数 << endl;
		if (msg.message == WM_DESTROY || msg.message == WM_QUIT || msg.message == WM_CLOSE) 
			return false;
		if (msg.message == WM_SYSKEYUP) goto To_跳过系统按键;
		//Windows窗口回调()
		TranslateMessage(&msg);		//转译消息
		DispatchMessage(&msg);		//将消息发送给WindowProc函数处理
	}
	else {
	To_跳过系统按键:
		assert(m_窗口GM->m_Root);
		
		if (!m_绘制) return true;
		//cout << "msg.message B:" << msg.message << " == " << m_帧数 << endl;
		
		if (m_是否有焦点) {
			m_Input->m_Key.lockKey[0] = GetKeyState(VK_CAPITAL) & 0x0001;
			f_取输入状态(m_Input);

			RECT rctA;
			GetClientRect((HWND)m_窗口钩柄, &rctA);
			

			GetCursorPos((POINT*)&m_Input->m_鼠标全局坐标);
			ScreenToClient((HWND)m_窗口钩柄, (POINT*)&m_Input->m_鼠标全局坐标);

			ScreenToClient((HWND)m_窗口钩柄, (POINT*)&rctA);
			m_窗口GM->窗口大小.x = -rctA.left;
			m_窗口GM->窗口大小.y = -rctA.top;
			//auto a = ClientToScreen((HWND)m_窗口钩柄, (POINT*)&m_Input.m_鼠标全局坐标);
		}
		
		f_ui_筛选焦点组件(m_窗口GM, { float32(m_Input->m_鼠标全局坐标.x), float32(m_Input->m_鼠标全局坐标.y) });

		
		//m_窗口GM->mf_输入执行前回调();
		f_ui_统一映射GPU内存();
		f_ui_执行输入设备事件(m_窗口GM, *m_Input);
		f_ui_统一解映射GPU内存();




		g时间end = clock();
		gdur = (double)(g时间end - g时间start);
		gdur = (gdur * 1000 / CLOCKS_PER_SEC);
		if (gdur > 33.2f || m_窗口GM->有输入事件) {
			g时间start = clock();
			m_窗口GM->有输入事件 = false;
		}
		else {
			Sleep(30);
		}
		

		//switch (S_光追后端::g_渲染状态) {
		//case E_离线渲染状态::e_光追渲染_序列:
		//case E_离线渲染状态::e_离线计算_序列:
		//default:
			f_widget_执行待添加部件();
			f_ui_动态销毁UI部件(m_窗口GM);
			f_ui_统一分配GPU内存();


			ivec2 m_ViewSize = { (int32)m_Size.x, (int32)m_Size.y };
			f_ui_绘制组件(m_窗口GM);

			f_ui_统一映射GPU内存();
			f_ui_更新UI部件属性(m_窗口GM, m_ViewSize);
			f_ui_统一解映射GPU内存();

			m_绘图框架->f_alloc(m_绘图设备配置);
			f_ui_绘制到屏幕(m_窗口GM, m_ViewSize);
			m_绘图框架->f_End(m_绘图设备配置);
		//}
		//memset(m_Input->m_Key.Keys, 0, sizeof(uint8) * 256);
	}
	
	return m_可视;
	
}

void S_Window::f_显示(bool s) {
	if (s) {
		ShowWindow((HWND)m_hWnd, SW_SHOW);
		//S_Engine::g_窗口容器[(uint64)m_hWnd] = this;
	}
	else {
		ShowWindow((HWND)m_hWnd, SW_HIDE);
		//S_Engine::g_窗口容器.erase((uint64)m_hWnd);
	}
	UpdateWindow((HWND)m_hWnd);
	
	m_可视 = s;
}

void S_Window::f_创建绘制面(S_绘图框架* frame, S_设备环境& dev, ivec2 viewSize) {
	m_绘图框架 = frame;
	HWND hWnd = (HWND)m_hWnd;
	//m_绘图框架->m_Ctx.m_绘图设备配置 = f_draw_创建绘图设备(dev);
	m_绘图设备配置 = f_draw_创建绘图设备(dev);
	m_绘图框架->f_创建窗口绘制面(m_绘图设备配置, m_hInstance, hWnd, viewSize, m_采样);
	
	//m_UIctx = S_Engine::m_UIctx;
	m_UIctx = new S_UI创建环境(dev, m_采样);
	m_UIctx->m_文字字号 = 12;
	m_窗口GM = f_create组件管理(*m_UIctx);
	m_窗口GM->mui_窗口 = this;
	
	f_ui加载字体(m_UIctx,
		{
			{
				{
					//{0x0000, 0x007F}, {0x4E00, 0x9FA5},
					//{0x0000, 0xFFFF},
		            0xFFFF,
				},

				"C:/Windows/Fonts/msyh.ttc",
				m_UIctx->m_文字字号,
				"雅黑"
			}
		}
	);

	/*f_ui加载字体(m_UIctx,
		{
			{
				{
					//{0x0000, 0x007F}, {0x4E00, 0x9FA5},
					{0x0000, 0xFFFF},
				},

				"D:/U/Project/晴圆等宽.ttc",
				m_UIctx->m_文字字号,
				"晴圆等宽"
			}
		}
	);*/

	
}

ivec2 S_Window::f_getSize() {
	int32 w, h;
	SDL_GetWindowSize((SDL_Window*)m_Window, &w, &h);
	return {w, h};
}

void S_Window::f_设置标题(std::wstring 标题) {
	SetWindowText((HWND)m_hWnd, 标题.c_str());
}

void S_Window::f_安装UI(C_Widget* ui) {
	f_ui_管理器添加根部件(m_窗口GM, ui);
	m_窗口GM->m_Root = ui;
	

	RECT rctA;
	GetClientRect((HWND)m_窗口钩柄, &rctA);
	ivec2 viewSize = { rctA.right - rctA.left, rctA.bottom - rctA.top };
	f_ui_绘制组件(m_窗口GM);
	f_ui_组件布局(m_窗口GM, { float32(rctA.left), float32(rctA.top), float32(viewSize.x), float32(viewSize.y) });
}

void S_Window::f_清除UI() {
	m_窗口GM->m_根部件切换组.clear();
	m_窗口GM->m_Root = nullptr;

}











LRESULT CALLBACK Windows窗口回调(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	S_Window* window;
	if (S_Engine::g_窗口容器.find((uint64)hWnd) == S_Engine::g_窗口容器.end()) {
		goto To_跳过事件;
	}
	else {
		window = S_Engine::g_窗口容器[(uint64)hWnd];
	}

	if (msg == WM_DESTROY || msg == WM_QUIT || msg == WM_CLOSE) {
		window->f_显示(false);
		if (S_Engine::g_窗口容器.size() <= 1) {
			//PostQuitMessage(0);
		}
		else {
			if (window && window->m_弹出窗口) {
				window->f_显示(false);
				return DefWindowProc(hWnd, msg, wParam, lParam);
			}
		}
		
		return DefWindowProc(hWnd, msg, wParam, lParam);
		PostQuitMessage(0);
	}

	//f_widget_结束输入法();
	if (!window || !(window->m_绘图框架)) goto To_跳过事件;
	if (!(window->m_窗口GM)) goto To_跳过事件;
	//S_Window* win = g_窗口容器[(S_结构对象指针)hWnd];
	switch (msg) {
		/*case WM_NCACTIVATE:
		{
			win->m_是否有焦点 = false;
			break;
		}
			//return DefWindowProc(hWnd, msg, wParam, lParam);

		case WM_ACTIVATEAPP:
			win->m_是否有焦点 = true;
			break;*/
	case WM_SYSCOMMAND:
		if (wParam == SC_CLOSE) {
			window->f_显示(false);
			return 0;
		}
		goto To_跳过事件;
		break;

		case WM_COMMAND:
		{
			int wmId = LOWORD(wParam);
			// 分析菜单选择:
			switch (wmId) {
			case IDM_EXIT:
				DestroyWindow(hWnd);
				break;
			default:
				return DefWindowProc(hWnd, msg, wParam, lParam);
			}
		}
		break;

		
		case WM_MOVE: {
			RECT rctA;
			GetWindowRect((HWND)window->m_窗口钩柄, &rctA);
			//const vec4 area = { float32(rctA.left), float32(rctA.top), window->m_Size.x, window->m_Size.y };
			window->m_窗口GM->窗口大小.x = rctA.left;
			window->m_窗口GM->窗口大小.y = rctA.top;
			break;
		}
		case WM_SIZE: {
			window->m_Size.x = LOWORD(lParam);
			window->m_Size.y = HIWORD(lParam);
			ivec2 m_ViewSize = { (int32)window->m_Size.x, (int32)window->m_Size.y };

			RECT rctA;
			GetWindowRect((HWND)window->m_窗口钩柄, &rctA);
			const vec4 area = { float32(rctA.left), float32(rctA.top), window->m_Size.x, window->m_Size.y };

			if (wParam == SIZE_MINIMIZED) {
				window->m_绘图框架->m_是否暂停 = true;
				window->m_绘制 = false;
			}
			else if (wParam == SIZE_MAXIMIZED) {			//窗口最大化
				window->m_绘图框架->m_是否暂停 = false;
				window->m_绘制 = true;
				if (window) {
					window->m_绘图框架->f_重置视口(window->m_窗口GM->m_UICtx->m_Ctx.m_绘图设备配置, m_ViewSize, window->m_采样);
					f_ui_组件布局(window->m_窗口GM, area);
				}

			}
			else if (wParam == SIZE_RESTORED) {
				window->m_绘制 = true;

				if (window) {
					window->m_绘图框架->f_重置视口(window->m_窗口GM->m_UICtx->m_Ctx.m_绘图设备配置, m_ViewSize, window->m_采样);
					//((S_Scene*)(win->m_底图Scene))->f_RView({ mClientWidth, mClientHeight });
					f_ui_组件布局(window->m_窗口GM, area);
				}
			}
			break;
		}
			
		//case WM_MOUSEACTIVATE:
		case WM_MOUSEMOVE:
			break;



		

		//输入法完成
		case WM_IME_ENDCOMPOSITION: {
			f_widget_set当前正在输入的文本(L"输入");
			//std::cout << "输入法完成 " << endl;
			break;
		}
		
		case WM_IME_NOTIFY: {
			HIMC hIMC = ImmGetContext(::GetFocus());
			DWORD dwConv, dwSent;
			bool b = ImmGetConversionStatus(hIMC, &dwConv, &dwSent);
			if ((dwConv & IME_CMODE_LANGUAGE) != IME_CMODE_NATIVE)
			{
				f_widget_结束输入法();
			}
			else if ((dwConv & IME_CMODE_CHINESE)) {
				f_widget_开始输入法();
			}

			/*if (lParam & GCS_RESULTREADSTR) {
				std::cout << "输入法进行 GCS_RESULTREADSTR :" << lParam << endl;
			}
			if (lParam & GCS_RESULTREADCLAUSE) {
				std::cout << "输入法进行 GCS_RESULTREADCLAUSE :" << lParam << endl;
			}
			if (lParam & GCS_RESULTCLAUSE) {
				std::cout << "输入法进行 GCS_RESULTCLAUSE :" << lParam << endl;
			}*/

			break;
		}
		
			//输入法进行
		case WM_IME_STARTCOMPOSITION: {
			HIMC hImc = ImmGetContext(hWnd);
			
			CANDIDATEFORM cand;
			cand.dwIndex = 0;
			cand.dwStyle = CFS_CANDIDATEPOS;
			POINT p;
			GetCursorPos(&p);
			
			p.x = GetSystemMetrics(SM_CXSIZE);
			p.y = GetSystemMetrics(SM_CYSIZE);

			auto 光标位置 = f_widget_get输入法窗口位置();

			cand.ptCurrentPos.x = 光标位置.x + p.x;
			cand.ptCurrentPos.y = 光标位置.y + p.y + 10;
			ImmSetCandidateWindow(hImc, &cand);
			//ImmReleaseContext(hWnd, himc);
			//ImmSetStatusWindowPos(himc, &pos);
			//ImmAssociateContext(hWnd, hIMC);
			//std::cout << "输入法进行 WM_IME_STARTCOMPOSITION :" << WM_IME_STARTCOMPOSITION << endl;

			f_widget_set当前正在输入的文本(L"输入法");

			ImmReleaseContext(hWnd, hImc);
			break;
		}
		

		//获取输入法字符
		case WM_IME_COMPOSITION: {
			auto hImc = ImmGetContext(hWnd);

			if (lParam & GCS_RESULTSTR) {
				auto txt = f_win32_get输入法文本(hImc);
				f_widget_发射输入法文本(txt);
			}

			ImmReleaseContext(hWnd, hImc);
			break;
		}
		
		

		/*case WM_CHAR:
		{
			auto lpcwInput = (LPCWSTR)GlobalAlloc(GPTR, sizeof(WCHAR) * 2);
			WCHAR wwww[2];
			wwww[0] = (wchar_t)(char)wParam;
			wwww[1] = 0;
			memcpy((void*)lpcwInput, wwww, sizeof(WCHAR) * 2);

			std::wstring str = wwww;
			
			//std::cout << "str == 文本输入" << f_WStringToString(str) << endl;
			break;
		}*/
			
		case WM_ENTERSIZEMOVE:
			window->m_绘图框架->m_是否暂停 = true;
			//mResizing = true;
			//mTimer.Stop();
			return 0;

		case WM_EXITSIZEMOVE:									//窗口移动
			window->m_绘图框架->m_是否暂停 = false;
			//mResizing = false;
			//m_Frame->f_重置视口({ mClientWidth, mClientHeight });
			return 0;
		


		case WM_GETMINMAXINFO:
			((MINMAXINFO*)lParam)->ptMinTrackSize.x = 200;
			((MINMAXINFO*)lParam)->ptMinTrackSize.y = 200;
			return 0;

		case WM_SYSCHAR:
		case WM_SYSDEADCHAR:
		case SM_SHOWSOUNDS:
			break;

		case WM_SETCURSOR: {
			if (f_window_set鼠标样式(C_Widget::g_鼠标样式) == false) {
				return DefWindowProc(hWnd, msg, wParam, lParam);
			}
			break;
		}
		

		case WM_DROPFILES: {
			HDROP hdrop = (HDROP)wParam;
			wchar_t sDropFilePath[MAX_PATH + 1];

			//获取
			int32 拖放文件个数数量 = 0;
			拖放文件个数数量 = DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0);
			for (int i = 0; i < 拖放文件个数数量; i++) {
				DragQueryFile(hdrop, i, sDropFilePath, sizeof(sDropFilePath));
				std::wstring 路径 = sDropFilePath;

				C_Widget管理::m_拖放文件名.push_back(路径);
			}
			DragFinish(hdrop);

			GetCursorPos((POINT*)&window->m_Input->m_鼠标全局坐标);
			ScreenToClient((HWND)window->m_窗口钩柄, (POINT*)&window->m_Input->m_鼠标全局坐标);
			C_Widget::g_鼠标.gPos = { float32(window->m_Input->m_鼠标全局坐标.x), float32(window->m_Input->m_鼠标全局坐标.y) };
			f_ui_文件拖入(window->m_窗口GM, { float32(window->m_Input->m_鼠标全局坐标.x), float32(window->m_Input->m_鼠标全局坐标.y) });
			break;
		}


		//============== 焦点 ===============
		case WM_KILLFOCUS:
			window->m_是否有焦点 = false;
			break;
		case WM_SETFOCUS:
			window->m_是否有焦点 = true;
			GetCursorPos((POINT*)&window->m_Input->m_鼠标全局坐标);
			ScreenToClient((HWND)window->m_窗口钩柄, (POINT*)&window->m_Input->m_鼠标全局坐标);
			C_Widget::g_鼠标.abs = { float32(window->m_Input->m_鼠标全局坐标.x), float32(window->m_Input->m_鼠标全局坐标.y) };
			break;

		




		/*case WM_PAINT: {
			// PAINTSTRUCT ps;
			// HDC hdc = BeginPaint(hWnd, &ps);
			// TODO: 在此处添加使用 hdc 的任何绘图代码...
			RECT rctA;
			GetWindowRect(hWnd, &rctA);

			auto* scene = g_要绘制场景[(S_结构对象指针)hWnd];
			if (scene) {
				scene->f_Update();
				scene->f_Render({ rctA .right - rctA .left, rctA .bottom - rctA .top});
			}

			//EndPaint(hWnd, &ps);
		}
		break;*/

		/*case EVENT_OBJECT_IME_SHOW: {
			std::cout << "输入法进行 EVENT_OBJECT_IME_SHOW:" << EVENT_OBJECT_IME_SHOW << endl;
			break;
		}
		case EVENT_OBJECT_IME_HIDE: {
			std::cout << "输入法进行 EVENT_OBJECT_IME_HIDE:" << EVENT_OBJECT_IME_HIDE << endl;
			break;
		}
		case EVENT_OBJECT_IME_CHANGE: {
			std::cout << "输入法进行 EVENT_OBJECT_IME_CHANGE:" << EVENT_OBJECT_IME_CHANGE << endl;
			break;
		}
		case EVENT_OBJECT_DRAGSTART: {
			std::cout << "输入法进行 EVENT_OBJECT_DRAGSTART:" << EVENT_OBJECT_DRAGSTART << endl;
			break;
		}
		case EVENT_OBJECT_DRAGCANCEL: {
			std::cout << "输入法进行 EVENT_OBJECT_DRAGCANCEL:" << EVENT_OBJECT_DRAGCANCEL << endl;
			break;
		}
		case EVENT_OBJECT_DRAGCOMPLETE: {
			std::cout << "输入法进行 EVENT_OBJECT_DRAGCOMPLETE:" << EVENT_OBJECT_DRAGCOMPLETE << endl;
			break;
		}
		case EVENT_OBJECT_DRAGENTER: {
			std::cout << "输入法进行 EVENT_OBJECT_DRAGCOMPLETE:" << EVENT_OBJECT_DRAGENTER << endl;
			break;
		}
		case EVENT_OBJECT_DRAGDROPPED: {
			std::cout << "输入法进行 EVENT_OBJECT_DRAGCOMPLETE:" << EVENT_OBJECT_DRAGDROPPED << endl;
			break;
		}*/

		/*case WM_IME_REQUEST:
			f_widget_开始输入法();
			std::cout << "WM_IME_REQUEST " << endl;
			break;
		case WM_IME_SETCONTEXT:
			std::cout << "输入法切换事件  WM_IME_SETCONTEXT " << endl;
			break;
		case IMN_CLOSESTATUSWINDOW:
			std::cout << "IMN_CLOSESTATUSWINDOW " << endl;
			break;
		case IMN_SETCOMPOSITIONWINDOW:
			std::cout << "IMN_SETCOMPOSITIONWINDOW " << endl;
			break;*/

		/*case WM_IME_KEYUP:
		{
			auto m_ImeChar = f_WStringToString({ (wchar_t)wParam });
			std::cout << "m_ImeChar WM_IME_ENDCOMPOSITION == " << m_ImeChar << endl;
		}*/

		//case WM_IME_SELECT:
		//	std::cout << "WM_IME_SELECT " << endl;
		//	break;
		//case WM_IME_CONTROL:
		//	std::cout << "WM_IME_CONTROL " << endl;
		//	break;


			break;
		default:
			To_跳过事件:
			return DefWindowProc(hWnd, msg, wParam, lParam);
	}

	return 0;
}







std::wstring f_win32_get输入法文本(HIMC hImc) {
	DWORD dwSize = ImmGetCompositionStringW(hImc, GCS_RESULTSTR, NULL, 0);
	dwSize += sizeof(WCHAR);
	LPCWSTR lpcwString = (LPCWSTR)GlobalAlloc(GPTR, dwSize);
	ImmGetCompositionStringW(hImc, GCS_RESULTSTR, (LPVOID)lpcwString, dwSize);
	auto lpcwInput = (LPCWSTR)GlobalAlloc(GPTR, dwSize);
	memcpy((void*)lpcwInput, lpcwString, dwSize);

	auto iSize = WideCharToMultiByte(936, 0, lpcwString, -1, NULL, 0, NULL, NULL);
	std::wstring 文本;
	文本.resize(iSize);
	WideCharToMultiByte(936, 0, lpcwString, -1, (LPSTR)(文本.data()), iSize, NULL, NULL);

	文本 = lpcwString;
	return 文本;
}
















